<template>
    <div class="tree-node" style="width:100%;display:block;">
        <li class="tree-node_content" @click="handleClick"
        :class="{'is-current':tree.store.currentNode === node}">
            <div v-for='(item,index) in propsName' :key="index" :style="{'width':item.width,'padding':index == 0 ? ('0 0 0 '+(15*(node.level-1)+'px')) :'2px 5px','flex-grow':1,display:'inline-block',overflow:'hidden','text-align':item.align || 'left'}">
                <p v-if="index==0" style="display:inline-block;margin:0;">
                    <span class="tree-node_expand-icon glyphicon" @click="handleExpandIconHandle" :class="{'glyphicon-chevron-right':!node.expanded,'glyphicon-chevron-down':node.expanded}"></span>
                    <input ref="checkbox" v-if="showCheckbox" class="node-checkbox" v-model="node.checked" 
                            :disabled="node.disabled" type="checkbox" @click.native.stop 
                            @change="handleCheckChange(node.checked,$event)"
                        />
                    <span class="node-loading" v-if="node.loading"><loading></loading></span>
                </p>
                <span>{{node.data[item.key]}}</span>
            </div>
        </li>
        <div class="tree-node_children" v-if="expanded">
            <table-tree-node v-if="node.childNodes" v-for="child in node.childNodes" 
          :node="child"
          :key="getNodeKey(child)"
          @node-expand="handleChildrenExpand"
          :propsName="propsName"
          ></table-tree-node>
        </div>
    </div>
</template>

<script>
import loading from "@/components/loading";
import emitter from "@/utils/emitter";
import { getNodeKey } from "./util";
export default {
  name: "TableTreeNode",
  componentName: "TableTreeNode",
  mixins: [emitter],
  data() {
    return {
      expanded: false,
      tree: null,
      showCheckbox: false,
      childNodeRendered: false
    };
  },
  props: {
    propsName: {
      type: Array,
      required: true
    },
    node: {
      default() {
        return {};
      }
    },
    props: {}
  },
  components: {
    loading
  },
  watch: {
    "node.expanded": function(val) {
      this.$nextTick(() => {
        this.expanded = val;
      });
    }
  },
  methods: {
    getNodeKey(node) {
      return getNodeKey(this.tree.nodeKey, node.data);
    },
    handleClick(ev) {
      const checkbox = this.$refs.checkbox;
      if (checkbox && checkbox[0] === ev.target) return;
      const store = this.tree.store;
      store.setCurrentNode(this.node);
      this.tree.$emit(
        "current-change",
        store.currentNode ? store.currentNode.data : null,
        store.currentNode
      );
      if (this.tree.expandOnClickNode) {
        this.handleExpandIconHandle();
      }
      this.tree.$emit("node-click", this.node.data, this.node, this);
    },
    handleExpandIconHandle() {
      if (this.expanded) {
        this.node.collapse();
      } else {
        this.node.expand();
      }
    },
    handleChildrenExpand(nodeData, node, instance) {
      this.broadcast("TableTreeNode", "tree-node-expand", node);
      this.tree.$emit("node-expand", nodeData, node, instance);
    },
    handleCheckChange(value, event) {
      this.node.setChecked(event.target.checked, this.tree.checkedStrictly);
      const setChildState = function(node) {
        if (node.childNodes.length === 0) return;
        for (let i = 0, j = node.childNodes.length; i < j; i++) {
          let n = node.childNodes[i];
          if(n.disabled) return;
          n.setChecked(event.target.checked, false);
          if (n.childNodes.length != 0) {
            setChildState(n);
          }
        }
      };
      this.$nextTick(() => {
        setChildState(this.node);
      });
    }
  },
  created() {
    const parent = this.$parent;
    if (parent.isTree) {
      this.tree = parent;
    } else {
      this.tree = parent.tree;
    }
    const tree = this.tree;
    if (!tree) {
      console.warn("Cant not find node's tree");
    }
    const props = tree.props || {};
    const childrenKey = props["children"] || "children";
    this.$watch(`node.data.${childrenKey}`, () => {
      // this.node.updateChildren();
    });
    this.showCheckbox = tree.showCheckbox;

    if (this.node.expanded) {
      this.expanded = true;
      this.childNodeRendered = true;
    }
    if (this.tree.accordion) {
      this.$on("tree-node-expand", node => {
        if (this.node !== node) {
          this.node.collapse();
        }
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.tree-node {
  outline: none;
  white-space: nowrap;
  .tree-node_content {
    display: flex;
    align-items: center;
    height: 26px;
    cursor: pointer;
    .node-checkbox {
      margin: -2px -2px 0 -2px;
      padding: 0;
      vertical-align: middle;
    }
    .node-loading {
      width: 20px;
      height: 15px;
      margin: 0 3px;
    }
  }
  .tree-node_children {
    display: block;
    overflow: hidden;
    background: transparent;
  }
  .is-current {
    background: #f5f7fa;
  }
}
</style>